using System;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Security;
#if !PocketPC && Framework20
    using Microsoft.Win32.SafeHandles;
    using System.Runtime.ConstrainedExecution;
#endif

namespace GeoFramework.IO.Serial
{
	#region Internal Structures

	[StructLayout(LayoutKind.Sequential)]
	internal struct DCB
	{
		#region Properties

		public int DCBlength;
		public uint BaudRate;
		public uint Flags;
		public ushort wReserved;
		public ushort XonLimit;
		public ushort XoffLimit;
		public byte ByteSize;
		public byte Parity;
		public byte StopBits;
		public sbyte XonChar;
		public sbyte XoffChar;
		public sbyte ErrorChar;
		public sbyte EofChar;
		public sbyte EvtChar;
		public ushort wReserved1;

		#endregion Attributes

		#region Properties

		public uint Binary
		{
			get { return Flags & 0x0001; }
			set { Flags = Flags & ~1U | value; }
		}
		public uint fParity
		{
			get { return (Flags >> 1) & 1; }
			set { Flags = Flags & ~(1U << 1) | (value << 1); }
		}
		public uint OutxCtsFlow
		{
			get { return (Flags >> 2) & 1; }
			set { Flags = Flags & ~(1U << 2) | (value << 2); }
		}
		public uint OutxDsrFlow
		{
			get { return (Flags >> 3) & 1; }
			set { Flags = Flags & ~(1U << 3) | (value << 3); }
		}
		public uint DtrControl
		{
			get { return (Flags >> 4) & 3; }
			set { Flags = Flags & ~(3U << 4) | (value << 4); }
		}
		public uint DsrSensitivity
		{
			get { return (Flags >> 6) & 1; }
			set { Flags = Flags & ~(1U << 6) | (value << 6); }
		}
		public uint TXContinueOnXoff
		{
			get { return (Flags >> 7) & 1; }
			set { Flags = Flags & ~(1U << 7) | (value << 7); }
		}
		public uint OutX
		{
			get { return (Flags >> 8) & 1; }
			set { Flags = Flags & ~(1U << 8) | (value << 8); }
		}
        public uint InX
        {
            get { return (Flags >> 9) & 1; }
            set { Flags = Flags & ~(1U << 9) | (value << 9); }
        }
		public uint fErrorChar
		{
			get { return (Flags >> 10) & 1; }
			set { Flags = Flags & ~(1U << 10) | (value << 10); }
		}
		public uint Null
		{
			get { return (Flags >> 11) & 1; }
			set { Flags = Flags & ~(1U << 11) | (value << 11); }
		}
		public uint RtsControl
		{
			get { return (Flags >> 12) & 3; }
			set { Flags = Flags & ~(3U << 12) | (value << 12); }
		}
        public uint AbortOnError
        {
            get { return (Flags >> 14) & 1; }
            set { Flags = Flags & ~(1U << 14) | (value << 14); }
        }

		#endregion Properties
	}

	[StructLayout(LayoutKind.Sequential)]
	internal struct COMSTAT
	{
		// See COMSTATFlags for flag documenation
		public COMSTATFlags Flags;
		// Number of bytes received by the serial provider but not yet read by a ReadFile operation. 
		public Int32 InQue;
		// Number of bytes of user data remaining to be transmitted for all write operations. This value will be zero for a nonoverlapped write. 
		public Int32 OutQue;
	}

	[StructLayout(LayoutKind.Sequential)]
	internal struct COMMTIMEOUTS
	{

		// Maximum time allowed to elapse between the arrival of two characters on 
		// the communications line, in milliseconds. During a ReadFile operation, 
		// the time period begins when the first character is received. If the 
		// interval between the arrival of any two characters exceeds this amount, 
		// the ReadFile operation is completed and any buffered data is returned. A 
		// value of zero indicates that interval time-outs are not used. 
		// A value of MAXDWORD, combined with zero values for both the 
		// ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier members, specifies 
		// that the read operation is to return immediately with the characters that 
		// have already been received, even if no characters have been received.
		public UInt32 ReadIntervalTimeout;

		// Multiplier used to calculate the total time-out period for read operations, 
		// in milliseconds. For each read operation, this value is multiplied by the 
		// requested number of bytes to be read. 
		public UInt32 ReadTotalTimeoutMultiplier;

		// Constant used to calculate the total time-out period for read operations, 
		// in milliseconds. For each read operation, this value is added to the 
		// product of the ReadTotalTimeoutMultiplier member and the requested number 
		// of bytes. 
		// A value of zero for both the ReadTotalTimeoutMultiplier and 
		// ReadTotalTimeoutConstant members indicates that total time-outs are not 
		// used for read operations.
		public UInt32 ReadTotalTimeoutConstant;
		

		// Multiplier used to calculate the total time-out period for write operations, 
		// in milliseconds. For each write operation, this value is multiplied by the 
		// number of bytes to be written. 
		public UInt32 WriteTotalTimeoutMultiplier;

		// Constant used to calculate the total time-out period for write operations, 
		// in milliseconds. For each write operation, this value is added to the 
		// product of the WriteTotalTimeoutMultiplier member and the number of bytes 
		// to be written. 
		// A value of zero for both the WriteTotalTimeoutMultiplier and 
		// WriteTotalTimeoutConstant members indicates that total time-outs are not 
		// used for write operations.
		public UInt32 WriteTotalTimeoutConstant;

	}

	[StructLayout(LayoutKind.Sequential)]
	internal struct COMMCONFIG
	{

		// Size of the structure, in bytes. 
		public Int32 Size;

		// Version number of the structure. This parameter can be 1. The version of 
		// the provider-specific structure should be included in the wcProviderData 
		// member. 
		public Int16 Version;

		// Reserved; do not use. 
		public Int16 Reserved;

		// Device-control block (DCB) structure for RS-232 serial devices. A DCB 
		// structure is always present regardless of the port driver subtype specified 
		// in the device's COMMPROP structure. 
		public DCB DCB;

		// Type of communications provider, and thus the format of the provider-
		// specific data. For a list of communications provider types, see the 
		// description of the COMMPROP structure. 
		public Int32 ProviderSubType;

		// Offset of the provider-specific data relative to the beginning of the 
		// structure, in bytes. This member is zero if there is no provider-specific 
		// data. 
		public Int32 ProviderOffset;

		// Size of the provider-specific data, in bytes. 
		public Int32 ProviderSize;

		// Optional provider-specific data. This member can be of any size or can
		// be omitted. Because the COMMCONFIG structure may be expanded in the future, 
		// applications should use the dwProviderOffset member to determine the 
		// location of this member. 
		public byte ProviderData;

	}

#if !Framework20
	[StructLayout(LayoutKind.Sequential)]
	internal struct OVERLAPPED : IDisposable
	{

		// Reserved for operating system use. This member, which specifies a 
		// system-dependent status, is valid when the GetOverlappedResult function 
		// returns without setting the extended error information to ERROR_IO_PENDING. 
		public UInt32 Internal;

		// Reserved for operating system use. This member, which specifies the length 
		// of the data transferred, is valid when the GetOverlappedResult function 
		// returns TRUE. 
		public UInt32 InternalHigh;

		// File position at which to start the transfer. The file position is a byte 
		// offset from the start of the file. The calling process sets this member 
		// before calling the ReadFile or WriteFile function. This member is ignored 
		// when reading from or writing to named pipes and communications devices and 
		// should be zero. 
		public UInt32 Offset;

		// High-order word of the byte offset at which to start the transfer. This 
		// member is ignored when reading from or writing to named pipes and 
		// communications devices and should be zero. 
		public UInt32 OffsetHigh;

		// Handle to an event set to the signaled state when the operation has been 
		// completed. The calling process must set this member either to zero or a 
		// valid event handle before calling any overlapped functions. To create an 
		// event object, use the CreateEvent function. 
		// Functions such as WriteFile set the event to the nonsignaled state before 
		// they begin an I/O operation.
		public IntPtr hEvent;

		#region IDisposable Members

		public void Dispose()
		{
			// TODO:  Add OVERLAPPED.Dispose implementation
		}

		#endregion
	}
#endif

	[StructLayout(LayoutKind.Sequential)]
	internal struct SerialTimeouts 
	{
		#region Attributes

		public int ReadIntervalTimeout;
		public int ReadTotalTimeoutMultiplier;
		public int ReadTotalTimeoutConstant;
		public int WriteTotalTimeoutMultiplier;
		public int WriteTotalTimeoutConstant;

		#endregion Attributes

		#region Constructors

        //public SerialTimeouts(int r1, int r2, int r3, int w1, int w2) 
        //{
        //    ReadIntervalTimeout = r1;
        //    ReadTotalTimeoutMultiplier = r2;
        //    ReadTotalTimeoutConstant = r3;
        //    WriteTotalTimeoutMultiplier = w1;
        //    WriteTotalTimeoutConstant = w2;
        //}

		#endregion Constructors

		#region Methods

		public override string ToString() 
		{
			return "ReadIntervalTimeout: " + ReadIntervalTimeout + "\r\n" +
				"ReadTotalTimeoutMultiplier: " + ReadTotalTimeoutMultiplier + "\r\n" +
				"ReadTotalTimeoutConstant: " + ReadTotalTimeoutConstant + "\r\n" +
				"WriteTotalTimeoutMultiplier: " + WriteTotalTimeoutMultiplier + "\r\n" +
				"WriteTotalTimeoutConstant: " + WriteTotalTimeoutConstant + "\r\n";
		}

		#endregion Methods
	}
#endregion

    #region P/Invoke Methods

#if !PocketPC && Framework20
    [SuppressUnmanagedCodeSecurity]
#endif
    internal 
#if Framework20
		static 
#else
		sealed
#endif	
		class NativeMethods
	{
#if !PocketPC
        [SuppressUnmanagedCodeSecurity]
#endif
		public static bool ClearCommError(SafeFileHandle handle, out uint lpErrors, out COMSTAT lpStat)
		{
			{
#if PocketPC
				if(Environment.OSVersion.Platform == System.PlatformID.WinCE)
				{
						return ClearCommErrorCompact(handle.DangerousGetHandle(), out lpErrors, out lpStat);
				}
				else
#endif
					return ClearCommErrorDesktop(handle.DangerousGetHandle(), out lpErrors, out lpStat);
			}
		}

#if !PocketPC
        [SuppressUnmanagedCodeSecurity]
        public static bool CancelIo(SafeFileHandle handle)
        {
            return CancelIoDesktop(handle.DangerousGetHandle());
        }
#endif

#if !PocketPC
        [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
#endif
		public static SafeFileHandle CreateFile(string lpFileName, SerialMode dwDesiredAccess,
			SerialShareMode dwShareMode, IntPtr lpSecurityAttributes, SerialCreationDisposition dwCreationDisposition,
			SerialFileAttributes dwFlagsAndAttributes, IntPtr hTemplateFile)
		{
#if PocketPC
				if(Environment.OSVersion.Platform == System.PlatformID.WinCE)
				{
					return new SafeFileHandle(CreateFileCompact(lpFileName, dwDesiredAccess, dwShareMode,
						lpSecurityAttributes, dwCreationDisposition,
						dwFlagsAndAttributes, hTemplateFile), true);	
				}
				else
#endif
				{
					return new SafeFileHandle(CreateFileDesktop(lpFileName, dwDesiredAccess, dwShareMode,
						lpSecurityAttributes, dwCreationDisposition,
						dwFlagsAndAttributes, hTemplateFile), true);
				}
		}

#if !PocketPC
		[SuppressUnmanagedCodeSecurity]
#endif
		public static bool FlushFileBuffers(SafeFileHandle handle)
		{
#if PocketPC
				if(Environment.OSVersion.Platform == System.PlatformID.WinCE)
					return FlushFileBuffersCompact(handle.DangerousGetHandle());
				else
#endif
					return FlushFileBuffersDesktop(handle.DangerousGetHandle());
		}

#if !PocketPC
		[SuppressUnmanagedCodeSecurity]
#endif
		public static bool EscapeCommFunction(SafeFileHandle handle, CommunicationEscapeCode escapeCode)
		{
#if PocketPC
				if(Environment.OSVersion.Platform == System.PlatformID.WinCE)
					return Convert.ToBoolean(EscapeCommFunctionCompact(handle.DangerousGetHandle(), (uint)escapeCode));
				else
#endif
					return Convert.ToBoolean(EscapeCommFunctionDesktop(handle.DangerousGetHandle(), (uint)escapeCode));
		}

#if !PocketPC
		[SuppressUnmanagedCodeSecurity]
#endif
		public static int SetupComm(SafeFileHandle handle, uint dwInQueue, uint dwOutQueue)
		{
#if PocketPC
				if(Environment.OSVersion.Platform == System.PlatformID.WinCE)
					return SetupCommCompact(handle.DangerousGetHandle(), dwInQueue, dwOutQueue);
				else
#endif
					return SetupCommDesktop(handle.DangerousGetHandle(), dwInQueue, dwOutQueue);
		}

#if !PocketPC
		[SuppressUnmanagedCodeSecurity]
#endif
		public static bool PurgeComm(SafeFileHandle handle, uint dwFlags)
		{
#if PocketPC
				if(Environment.OSVersion.Platform == System.PlatformID.WinCE)
					return PurgeCommCompact(handle.DangerousGetHandle(), dwFlags);
				else
#endif
					return PurgeCommDesktop(handle.DangerousGetHandle(), dwFlags);
		}

#if !PocketPC
		[SuppressUnmanagedCodeSecurity]
		public static bool ReadFile(SafeFileHandle handle, byte[] lpBuffer,
			uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, ref NativeOverlapped lpOverlapped)
		{
				return ReadFileDesktop(handle.DangerousGetHandle(), lpBuffer, nNumberOfBytesToRead, out lpNumberOfBytesRead, ref lpOverlapped);
		}
#else
        public static bool ReadFile(SafeFileHandle handle, byte[] lpBuffer,
            uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped)
        {
            if (Environment.OSVersion.Platform == System.PlatformID.WinCE)
                return ReadFileCompact(handle.DangerousGetHandle(), lpBuffer, nNumberOfBytesToRead, out lpNumberOfBytesRead, lpOverlapped);
            else
                return ReadFileDesktop(handle.DangerousGetHandle(), lpBuffer, nNumberOfBytesToRead, out lpNumberOfBytesRead, lpOverlapped);
        }
#endif

#if !PocketPC
		[SuppressUnmanagedCodeSecurity]
		public static bool WriteFile(SafeFileHandle handle, byte[] lpBuffer,
			uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten,
			System.Threading.NativeOverlapped lpOverlapped)
		{		
				return WriteFileDesktop(handle.DangerousGetHandle(), lpBuffer, nNumberOfBytesToWrite, out lpNumberOfBytesWritten, ref lpOverlapped);
		}
#else
        public static bool WriteFile(SafeFileHandle handle, byte[] lpBuffer,
            uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten,
            IntPtr lpOverlapped)
        {
            if (Environment.OSVersion.Platform == System.PlatformID.WinCE)
                return WriteFileCompact(handle.DangerousGetHandle(), lpBuffer, nNumberOfBytesToWrite, out lpNumberOfBytesWritten, lpOverlapped);
            else
                return WriteFileDesktop(handle.DangerousGetHandle(), lpBuffer, nNumberOfBytesToWrite, out lpNumberOfBytesWritten, lpOverlapped);
        }
#endif

#if !PocketPC
		[SuppressUnmanagedCodeSecurity]
#endif
		public static bool SetCommTimeouts(SafeFileHandle handle, ref SerialTimeouts lpCommTimeouts)
		{
//			if(handle.IsInvalid || handle.IsClosed)
//				return false;

			//lock(CreateFileSerializer)
			{
#if PocketPC
				if(Environment.OSVersion.Platform == System.PlatformID.WinCE)
					return SetCommTimeoutsCompact(handle.DangerousGetHandle(), ref lpCommTimeouts);
				else
#endif
					return SetCommTimeoutsDesktop(handle.DangerousGetHandle(), ref lpCommTimeouts);
			}
		}

#if !PocketPC
		[SuppressUnmanagedCodeSecurity]
#endif
		public static bool SetCommState(SafeFileHandle handle, ref DCB lpDCB)
		{
//			if(handle.IsInvalid || handle.IsClosed)
//				return false;

			//lock(CreateFileSerializer)
			{
#if PocketPC
				if(Environment.OSVersion.Platform == System.PlatformID.WinCE)
					return SetCommStateCompact(handle.DangerousGetHandle(), ref lpDCB);
				else
#endif
					return SetCommStateDesktop(handle.DangerousGetHandle(), ref lpDCB);
			}
		}


#if PocketPC
		#region Windows CE API's
		[DllImport("coredll.dll", EntryPoint="CreateFile", CharSet = CharSet.Auto, SetLastError = true)]
		private static extern IntPtr CreateFileCompact(string lpFileName, SerialMode dwDesiredAccess,
			SerialShareMode dwShareMode, IntPtr lpSecurityAttributes, SerialCreationDisposition dwCreationDisposition,
			SerialFileAttributes dwFlagsAndAttributes, IntPtr hTemplateFile);

		[DllImport("coredll.dll", EntryPoint="ClearCommError", SetLastError = false)]
		private static extern bool ClearCommErrorCompact(IntPtr hFile, out uint lpErrors, out COMSTAT lpStat);

		[DllImport("coredll.dll", EntryPoint="ReadFile", SetLastError = false)]
		private static extern bool ReadFileCompact(IntPtr hFile, byte[] lpBuffer,
			uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped);

		[DllImport("coredll.dll", EntryPoint="WriteFile", SetLastError = false)]
		private static extern bool WriteFileCompact(IntPtr hFile, byte [] lpBuffer,
			uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten,
			IntPtr lpOverlapped);
		//private static extern bool WriteFileCompact(IntPtr handle, byte[] lpBuffer, int nNumberOfBytesToWrite, out int lpNumberOfBytesWritten, System.Threading.NativeOverlapped lpOverlapped);

		[DllImport("coredll.dll", EntryPoint="EscapeCommFunction", SetLastError = false)]
		private static extern int EscapeCommFunctionCompact(IntPtr hFile, uint dwFunc);

		[DllImport("coredll.dll", EntryPoint="SetCommTimeouts", SetLastError = false)]
		private static extern bool SetCommTimeoutsCompact(IntPtr hFile, [In] ref SerialTimeouts lpCommTimeouts);

		[DllImport("coredll.dll", EntryPoint="SetCommState", SetLastError = false)]
		private static extern bool SetCommStateCompact(IntPtr hFile, [In] ref DCB lpDCB);

		[DllImport("coredll.dll", EntryPoint="SetupComm", SetLastError = false)]
		public extern static int SetupCommCompact(IntPtr handle, uint dwInQueue, uint dwOutQueue);

		[DllImport("coredll.dll", EntryPoint="FlushFileBuffers", SetLastError = false)]
		private static extern bool FlushFileBuffersCompact(IntPtr handle);

		[DllImport("coredll.dll", EntryPoint="PurgeComm", SetLastError = false)]
		private static extern bool PurgeCommCompact(IntPtr handle, uint dwFlags);
		#endregion
#endif

		#region  Desktop API 
		[DllImport("kernel32.dll", EntryPoint="CreateFile", SetLastError = true, CharSet=CharSet.Auto)]
#if !PocketPC && Framework20
         [SuppressUnmanagedCodeSecurity]
         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
#endif
		private static extern IntPtr CreateFileDesktop(string lpFileName, SerialMode dwDesiredAccess,
			SerialShareMode dwShareMode, IntPtr lpSecurityAttributes, SerialCreationDisposition dwCreationDisposition,
			SerialFileAttributes dwFlagsAndAttributes, IntPtr hTemplateFile);

        [DllImport("kernel32.dll", EntryPoint = "CancelIo", SetLastError = false)]
#if !PocketPC && Framework20
        [SuppressUnmanagedCodeSecurity]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
#endif
        private static extern bool CancelIoDesktop(IntPtr hFile);

        [DllImport("kernel32.dll", EntryPoint = "ClearCommError", SetLastError = false)]
#if !PocketPC && Framework20
        [SuppressUnmanagedCodeSecurity]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
#endif
		private static extern bool ClearCommErrorDesktop(IntPtr hFile, out uint lpErrors, out COMSTAT lpStat);

        [DllImport("kernel32.dll", EntryPoint = "EscapeCommFunction", SetLastError = false)]
#if !PocketPC && Framework20
        [SuppressUnmanagedCodeSecurity]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
#endif
		private static extern int EscapeCommFunctionDesktop(IntPtr hFile, uint dwFunc);

        [DllImport("kernel32.dll", EntryPoint = "ReadFile", SetLastError = true)]
#if !PocketPC && Framework20
        [SuppressUnmanagedCodeSecurity]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
#endif
#if PocketPC
        public static extern bool ReadFileDesktop(IntPtr hFile, [Out] byte[] lpBuffer, uint nNumberOfBytesToRead,
           out uint lpNumberOfBytesRead, IntPtr lpOverlapped);
#else
        public static extern bool ReadFileDesktop(IntPtr hFile, [Out] byte[] lpBuffer, uint nNumberOfBytesToRead,
           out uint lpNumberOfBytesRead, [In] ref System.Threading.NativeOverlapped lpOverlapped);
#endif
     
        [DllImport("kernel32.dll", EntryPoint = "WriteFile", SetLastError = false)]
#if !PocketPC && Framework20
        [SuppressUnmanagedCodeSecurity]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
#endif
#if PocketPC
        public static extern bool WriteFileDesktop(IntPtr hFile, byte[] lpBuffer,
                uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten,
                IntPtr lpOverlapped);
#else
        public static extern bool WriteFileDesktop(IntPtr hFile, byte[] lpBuffer,
                uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten,
                [In] ref System.Threading.NativeOverlapped lpOverlapped);
#endif

        [DllImport("kernel32.dll", EntryPoint = "SetCommTimeouts", SetLastError = false)]
#if !PocketPC && Framework20
        [SuppressUnmanagedCodeSecurity]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
#endif
		private static extern bool SetCommTimeoutsDesktop(IntPtr hFile, [In] ref SerialTimeouts lpCommTimeouts);

        [DllImport("kernel32.dll", EntryPoint = "SetCommState", SetLastError = false)]
#if !PocketPC && Framework20
        [SuppressUnmanagedCodeSecurity]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
#endif
		private static extern bool SetCommStateDesktop(IntPtr hFile, [In] ref DCB lpDCB);

        [DllImport("kernel32.dll", EntryPoint = "SetupComm", SetLastError = false)]
#if !PocketPC && Framework20
        [SuppressUnmanagedCodeSecurity]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
#endif
		private static extern int SetupCommDesktop(IntPtr handle, uint dwInQueue, uint dwOutQueue);

		//		[DllImport("kernel32.dll", EntryPoint="GetCommState", SetLastError = false)]
		//		private static extern bool GetCommStateDesktop(IntPtr handle, ref DCB lpDCB);

		//		[DllImport("kernel32.dll", EntryPoint="BuildCommDCB", SetLastError = false)]
		//		private static extern bool BuildCommDCBDesktop(string def, ref DCB lpDCB);
		//
		//		[DllImport("kernel32.dll", EntryPoint="GetLastError", SetLastError = false)]
		//		private static extern int GetLastErrorDesktop();

        [DllImport("kernel32.dll", EntryPoint = "FlushFileBuffers", SetLastError = false)]
#if !PocketPC && Framework20
        [SuppressUnmanagedCodeSecurity]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
#endif
		private static extern bool FlushFileBuffersDesktop(IntPtr handle);

        [DllImport("kernel32.dll", EntryPoint = "PurgeComm", SetLastError = false)]
#if !PocketPC && Framework20
        [SuppressUnmanagedCodeSecurity]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
#endif
		private static extern bool PurgeCommDesktop(IntPtr handle, uint dwFlags);
		#endregion
		//#endif
	}


	#endregion

}
